/*******************************************************************************
 * Copyright (c) 2011 Erik Byström.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
package se.slackers.automatunes.ui;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author Erik Byström
 * 
 */
public class ParameterSet {
	private final Map<String, Parameter<?, ?>> parameters = new HashMap<String, Parameter<?, ?>>();
	private ParameterSet chain;

	public ParameterSet() {
	}

	public ParameterSet(final Parameter<?, ?>... params) {
		add(params);
	}

	public ParameterSet(final ParameterSet set) {
		for (final Entry<String, Parameter<?, ?>> entry : set.parameters.entrySet()) {
			parameters.put(entry.getKey(), entry.getValue());
		}
	}

	public ParameterSet chain(final ParameterSet next) {
		if (chain == null) {
			chain = next;
		} else {
			chain.chain(next);
		}
		return this;
	}

	public void disconnect() {
		for (final Parameter<?, ?> p : parameters.values()) {
			p.disconnect();
		}

		if (chain != null) {
			chain.disconnect();
		}
	}

	public final ParameterSet add(final Parameter<?, ?>... params) {
		for (final Parameter<?, ?> p : params) {
			parameters.put(p.name(), p);
		}
		return this;
	}

	public Parameter<?, ?> find(final String name) {
		final Parameter<?, ?> p = parameters.get(name);
		if (p == null && chain != null) {
			return chain.find(name);
		}
		return p;
	}

	public int size() {
		return parameters.size() + (chain != null ? chain.size() : 0);
	}

	@SuppressWarnings("unchecked")
	public Float getFloat(final String name) {
		final Parameter<Float, ?> p = (Parameter<Float, ?>) find(name);
		if (p == null) {
			throw new IllegalArgumentException("Unknown parameter " + name);
		}

		return p.value();
	}

	@SuppressWarnings("unchecked")
	public int getInt(final String name) {
		final Parameter<Integer, ?> p = (Parameter<Integer, ?>) find(name);
		if (p == null) {
			throw new IllegalArgumentException("Unknown parameter " + name);
		}

		return p.value();
	}

	@SuppressWarnings("unchecked")
	public boolean getBoolean(final String name) {
		final Parameter<Boolean, ?> p = (Parameter<Boolean, ?>) find(name);
		if (p == null) {
			throw new IllegalArgumentException("Unknown parameter " + name);
		}

		return p.value();
	}

	public Collection<Parameter<?, ?>> collection() {
		final List<Parameter<?, ?>> params = new LinkedList<Parameter<?, ?>>();
		if (chain != null) {
			params.addAll(chain.collection());
		}
		params.addAll(parameters.values());
		return params;
	}

}
